package com.ccut.xunfeiSpringboot.service.impl;

import com.ccut.xunfeiSpringboot.dto.ChatRequest;
import com.ccut.xunfeiSpringboot.dto.KnowledgeGraphDTO;
import com.ccut.xunfeiSpringboot.mapper.KnowledgeGraphMapper;
import com.ccut.xunfeiSpringboot.model.RoleContent;
import com.ccut.xunfeiSpringboot.service.BaseService;
import com.ccut.xunfeiSpringboot.service.KnowledgeGraphService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.net.MalformedURLException;
import java.security.SignatureException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;

@Service
public class KnowledgeGraphServiceImpl implements KnowledgeGraphService {

    @Autowired
    private KnowledgeGraphMapper knowledgeGraphMapper;

    @Autowired
    private BaseService baseService;

    @Override
    public KnowledgeGraphDTO getNodesAndLinksByAI(String prompt,Integer userId) throws MalformedURLException, SignatureException {
        ChatRequest chatRequest = new ChatRequest();
        chatRequest.setUserId(Long.valueOf(userId));
        List<RoleContent> messages = new ArrayList<>();
        messages.add(new RoleContent("system", "你是一个精通各种知识的机器人，可以按照下面的信息给我生成知识点之间的关系。"));
        String basePrompt = """
                请根据{data}，生成一个符合以下格式的知识点树状关系图数据。
                                
                ### 输出格式：
                - 包含两个主要部分：nodes（节点列表）和 links（连接关系列表）
                - 每个 node 必须包含三个字段：
                  - id: 唯一标识符（字符串类型，全局唯一）
                  - label: 节点名称（字符串）
                  - type: 节点类型，只能是 "root"、"father" 或 "child"
                    - "root": 表示根节点，有且仅有一个
                    - "father": 表示一级子节点，直接隶属于 root
                    - "child": 表示后代节点，每个 child 只能有一个唯一的父节点
                                
                - links 表示父子关系：
                  - source: 父节点的 id
                  - target: 子节点的 id
                                
                ### 规则：
                1. 整个结构中只有一个 "root" 类型节点，且该节点的id为0。
                2. 所有节点的 id 必须唯一，不能重复。
                3. 一个父节点可以有多个子节点。
                4. node的type类型为child的也可以作为父节点，其子节点的类型仍为child，即允许在links关系中id为source的node与id为target的两个节点type均为child。
                                
                ### 请以严格的 JSON 格式返回，且每个字段都要用""包围，使之能被com.alibaba.fastjson2解析为Java实体类对象，树状关系层级数要求大于4层，不包含任何额外文本。
                示例输出格式：
                {
                  "nodes": [
                    { "id": "0", "label": "关羽", "type": "root" },
                    { "id": "1", "label": "刘备", "type": "father" },
                    { "id": "2", "label": "小羽", "type": "child" },
                    { "id": "3", "label": "张飞", "type": "child" },
                    { "id": "4", "label": "赵云", "type": "child" },
                    { "id": "5", "label": "小乔", "type": "child" },
                    { "id": "6", "label": "小王", "type": "child" },
                    { "id": "7", "label": "大王", "type": "child" }
                  ],
                  "links": [
                    { "source": "0", "target": "1" },
                    { "source": "0", "target": "2" },
                    { "source": "1", "target": "3" },
                    { "source": "1", "target": "4" },
                    { "source": "3", "target": "5" },
                    { "source": "3", "target": "6" },
                    { "source": "6", "target": "7" }
                  ]
                }
                """;
        prompt = basePrompt.replace("{data}", prompt);
        messages.add(new RoleContent("user", prompt));
        chatRequest.setDeepThinking(true);
        chatRequest.setNetworkSearch(false);
        chatRequest.setQuestion("");
        chatRequest.setMessages(messages);
        return baseService.recommendKnowledgeGraph(chatRequest);
    }
}
